package com.hqhy.like.front.order.service.impl;

import com.hqhy.like.common.enumerator.ServiceCode;
import com.hqhy.like.common.ex.ServiceException;
import com.hqhy.like.common.pojo.authentication.CurrentPrincipal;
import com.hqhy.like.common.pojo.vo.PageData;
import com.hqhy.like.front.order.dao.cache.ICartCacheRepository;
import com.hqhy.like.front.order.dao.persist.repository.IDishesRepository;
import com.hqhy.like.front.order.dao.persist.repository.IOrderDetailsRepository;
import com.hqhy.like.front.order.dao.persist.repository.IOrderRepository;
import com.hqhy.like.front.order.dao.persist.repository.ITableRepository;
import com.hqhy.like.front.order.pojo.entity.Order;
import com.hqhy.like.front.order.pojo.entity.OrderDetails;
import com.hqhy.like.front.order.pojo.entity.Table;
import com.hqhy.like.front.order.pojo.param.*;
import com.hqhy.like.front.order.pojo.po.CartPO;
import com.hqhy.like.front.order.pojo.vo.*;
import com.hqhy.like.front.order.service.IOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
@Slf4j
public class OrderServiceImpl implements IOrderService {

    @Value("${like.dao.default-query-page-size}")
    private Integer defaultQueryPageSize;
    @Autowired
    private IOrderRepository orderRepository;
    @Autowired
    private IOrderDetailsRepository orderDetailsRepository;
    @Autowired
    private IDishesRepository dishesRepository;
    @Autowired
    private ITableRepository tableRepository;
    @Autowired
    private ICartCacheRepository cartCacheRepository;

    public OrderServiceImpl() {
        log.debug("创建业务类对象：OrderServiceImpl");
    }
    @Override
    public Long create(CurrentPrincipal currentPrincipal, OrderAddNewParam orderAddNewParam) {
        log.debug("开始处理【创建订单】的业务，当事人: {}，新建订单参数类：{}", currentPrincipal,orderAddNewParam);
        //TODO 预约功能后续开发...(需要时间段算法支撑)

        //根据tableId查询出桌台，是否可用
        Integer tableId = orderAddNewParam.getTableId();
        TableStandardVO tableVO = tableRepository.getStandardById(tableId);
        if (tableVO == null){
            String message = "创建订单失败，桌台数据不存在！";
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }
        if (tableVO.getIsEnable() == 1){
            String message = "创建订单失败，此桌台不可用！";
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
        }
        if (tableVO.getIsAvailable() == 1){
            String message = "创建订单失败，桌台【"+tableVO.getTableName()+"】正在使用中，请重新选择！";
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
        }
        //菜品总价
        BigDecimal totalPrice = BigDecimal.ZERO;
        //菜品总数量
        Integer dishesTotalNum = 0;
        //每个菜品数量集合
        List<Integer> dishesNumList = new ArrayList<>();

        //查询菜品，查询结果为空（抛异常，创建订单失败，商品数据不存在）
        Integer[] dishesIdList = orderAddNewParam.getDishesIdList();
        List<DishesStandardVO> dishesList = new ArrayList<>();
        for (int i = 0; i < dishesIdList.length; i++) {
            DishesStandardVO dish = dishesRepository.getStandardById(dishesIdList[i]);
            if (dish == null){
                String message = "创建订单失败，部分菜品数据不存在！";
                throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
            }

            dishesList.add(dish);
            //查询是否在购物车中
            CartPO cartPO = cartCacheRepository.getByUserAndDishes(currentPrincipal.getId(), dishesIdList[i]);
            if (cartPO == null){
                String message = "创建订单失败，购物车数据异常，请返回购物车并重新下单！";
                throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
            }
            //TODO 后续实现：查询菜品是否上架（抛异常，创建订单失败，商品【xx】已下架）

            //TODO 后续实现：查询菜品库存，超过库存（抛异常，创建订单失败，该菜品达到库存上限）

            //TODO 后续实现：减库存表

            Integer dishNum = cartPO.getDishNum();
            dishesNumList.add(dishNum);
            dishesTotalNum += dishNum;

            BigDecimal dishPrice = dish.getDishPrice();
            BigDecimal multiply = dishPrice.multiply(new BigDecimal(dishNum));//multiply乘积
            totalPrice = totalPrice.add(multiply);
        }
        //插入订单表
        Order order = new Order();
        order.setCustomerId(currentPrincipal.getId());
        order.setCustomerUsername(currentPrincipal.getUsername());
        order.setOrderNo(getUniqueCode());
        order.setTableName(tableVO.getTableName());
        order.setDishNum(dishesTotalNum);
        order.setOrderMethod(orderAddNewParam.getOrderMethod());
        order.setTotalPrice(totalPrice);
        order.setOrderState(ORDER_STATE_WAITING);
        order.setTakingStatus(NORMAL_PICKING_ORDER);
        int rows = orderRepository.insert(order);
        if (rows != 1) {
            String message = "创建订单失败，服务器忙，请稍后再试！";
            throw new ServiceException(ServiceCode.ERROR_INSERT, message);
        }
        //插入订单详情表
        for (int i = 0; i < dishesList.size(); i++) {
            DishesStandardVO dish = dishesList.get(i);
            OrderDetails orderDetails = new OrderDetails();
            orderDetails.setOrderId(order.getId());
            orderDetails.setDishId(dish.getId());
            orderDetails.setDishName(dish.getDishName());
            orderDetails.setDishCuisine(dish.getDishCuisine());
            orderDetails.setDishPrice(dish.getDishPrice());
            orderDetails.setDishImg(dish.getDishImg());
            orderDetails.setDishNum(dishesNumList.get(i));
            rows = orderDetailsRepository.insert(orderDetails);
            if (rows != 1) {
                String message = "创建订单失败，服务器忙，请稍后再试！";
                throw new ServiceException(ServiceCode.ERROR_INSERT, message);
            }
        }
        //更新桌台是否空闲信息
        Table table = new Table();
        table.setId(tableId);
        table.setIsAvailable(TABLE_UN_AVAILABLE);//设置桌台使用中 不空闲
        rows = tableRepository.updateById(table);
        if (rows != 1) {
            String message = "创建订单失败，服务器忙，请稍后再试！";
            throw new ServiceException(ServiceCode.ERROR_UPDATE, message);
        }
        //清空购物车
        for (int i = 0; i < dishesIdList.length; i++) {
            cartCacheRepository.deleteByUserAndDishes(currentPrincipal.getId(), dishesIdList[i]);
        }
        return order.getId();
    }

    @Override
    public void deleteById(Long orderId) {
        log.debug("开始处理【删除订单】的业务，订单id：{}",orderId);
        OrderStandardVO queryResult = orderRepository.getStandardById(orderId);
        if (queryResult==null){
            String message = "删除订单失败，订单数据不存在！";
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }
        int rows = orderRepository.deleteById(orderId);
        if (rows != 1){
            String message = "删除订单失败，订单数据不存在！";
            throw new ServiceException(ServiceCode.ERROR_DELETE, message);
        }
    }

    @Override
    public void updateInfoById(Long orderId, OrderUpdateInfoParam orderUpdateInfoParam) {
        log.debug("开始处理【修改订单数据】的业务，订单id: {}，订单更新信息类：{}", orderId,orderUpdateInfoParam);
        OrderStandardVO queryResult = orderRepository.getStandardById(orderId);
        if (queryResult == null){
            String message = "更新订单失败，订单数据不存在！";
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }
        Order order = new Order();
        BeanUtils.copyProperties(orderUpdateInfoParam,order);
        order.setId(orderId);
        int rows = orderRepository.updateById(order);
        if (rows != 1){
            String message = "修改订单失败，服务器忙，请稍后再尝试！";
            throw new ServiceException(ServiceCode.ERROR_UPDATE, message);
        }
    }

    @Override
    public OrderStandardVO getStandardById(Long orderId) {
        log.debug("开始处理【根据订单id查询订单】的业务，订单id: {}", orderId);
        OrderStandardVO order = orderRepository.getStandardById(orderId);
        if (order == null){
            String message = "查询订单失败，尝试访问的数据不存在！";
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }
        return order;
    }

    @Override
    public OrderTableVO getStandardByOrderNo(String orderNo) {
        log.debug("开始处理【根据订单编号查询订单桌台数据】的业务，订单编号: {}", orderNo);
        return orderRepository.getStandardByOrderNo(orderNo);
    }

    @Override
    public PageData<OrderStandardVO> listAllCheckByMethod(Integer orderMethod, Integer pageNum, Integer pageSize) {
        log.debug("开始处理【根据下单方式查询所有确认订单页面的订单】的业务，下单方式: {}，页码: {}，每页记录数：{}", orderMethod, pageNum, pageSize);
        return orderRepository.listAllCheckByMethod(pageNum,pageSize,orderMethod);
    }

    @Override
    public PageData<OrderStandardVO> listAllCheckByMethod(Integer orderMethod, Integer pageNum) {
        log.debug("开始处理【根据下单方式查询所有确认订单页面的订单】的业务，下单方式: {}，页码: {}", orderMethod, pageNum);
        return orderRepository.listAllCheckByMethod(pageNum,defaultQueryPageSize,orderMethod);
    }

    @Override
    public PageData<OrderTableVO> listOrderForTable(OrderQueryParam orderQueryParam) {
        log.debug("开始处理【查询订单桌台数据】的业务，查询订单桌台信息参数类: {}", orderQueryParam);
        Integer pageSize = orderQueryParam.getPageSize();
        Integer pageNum = orderQueryParam.getPageNum();
        if (pageNum == null){
            orderQueryParam.setPageNum(1);
        }
        if (pageSize == null){
            orderQueryParam.setPageSize(defaultQueryPageSize);
        }
        return orderRepository.listOrderForTable(orderQueryParam);
    }

    @Override
    public PageData<OrderStandardVO> searchByCondition(OrderSearchParam orderSearchParam) {
        log.debug("开始处理【根据条件查询订单】的业务，查询订单详情参数类: {}", orderSearchParam);
        Integer pageSize = orderSearchParam.getPageSize();
        Integer pageNum = orderSearchParam.getPageNum();
        if (pageNum == null){
            orderSearchParam.setPageNum(1);
        }
        if (pageSize == null){
            orderSearchParam.setPageSize(defaultQueryPageSize);
        }
        return orderRepository.searchByCondition(orderSearchParam);
    }

    @Override
    public PageData<OrderStandardVO> listByStateAndMethod(OrderSearchParam orderSearchParam) {
        log.debug("开始处理【根据下单方式和订单状态查询订单】的业务，查询订单详情参数类: {}", orderSearchParam);
        Integer pageSize = orderSearchParam.getPageSize();
        Integer pageNum = orderSearchParam.getPageNum();
        if (pageNum == null){
            orderSearchParam.setPageNum(1);
        }
        if (pageSize == null){
            orderSearchParam.setPageSize(defaultQueryPageSize);
        }
        return orderRepository.listByStateAndMethod(orderSearchParam);
    }

    private static synchronized String getUniqueCode(){
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
//        int random = new Random().nextInt(900000000);
        long timestamp = System.currentTimeMillis();
        String time = format.format(new Date());
        return timestamp+time;
    }

}
